<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>右键菜单</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #context-menu {
            position: fixed;
            width: 300px;
            height: 400px;
            background-image: linear-gradient(235deg, #f7f0ac, #acf7f0, #f0acf7);
            transition: all 0.3s ease-in-out;
            border-radius: 5px;
            /* 使用  display: none; 会造成边界判断失败 */
            visibility: hidden;
            opacity: 0;
            z-index: 9999;

        }

        .menu-item {
            padding: 10px;
            cursor: pointer;
        }

        .menu-item:hover {
            background-color: #d6d6d6;
        }

        .rebound {
            animation: rebound .5s;
        }

        @keyframes rebound {
            0% {
                transform: translate(-100%, 0);
                opacity: 0;
            }

            40% {
                transform: translate(10%, 0);
            }

            70% {
                transform: translate(-5%, 0);
            }

            100% {
                transform: translate(0);
                opacity: 1;
            }
        }
    </style>
</head>

<body>


    <div id="context-menu">
        <div class="menu-item">菜单项1</div>
        <div class="menu-item">菜单项2</div>
        <div class="menu-item">菜单项3</div>
    </div>

    <script>
        const contextMenu = document.getElementById('context-menu');

        function setPosition(event, menu) {
            // 获取窗口宽度和高度
            const screenWidth = window.innerWidth;
            const screenHeight = window.innerHeight;
            // 获取菜单宽度和高度
            const menuWidth = menu.offsetWidth;
            const menuHeight = menu.offsetHeight;
            // 获取鼠标在页面中的位置
            const x = event.clientX;
            const y = event.clientY;
            // 计算菜单的调整后的水平位置和垂直位置
            const adjustedX = (x + menuWidth) >= screenWidth ? (x - menuWidth) : x; // 检查是否超出右侧边界
            const adjustedY = (y + menuHeight) >= screenHeight ? (y - menuHeight) : y; // 检查是否超出底部边界
            // 如果超出右侧边界，让菜单反弹一下
            if (adjustedX !== x) {
                menu.classList.add('rebound');
                setTimeout(() => {
                    menu.classList.remove('rebound');
                }, 1000);
            }
            // 设置菜单的位置
            menu.style.left = adjustedX + 'px';
            menu.style.top = adjustedY + 'px';
        }

        document.addEventListener('contextmenu', function (event) {
            event.preventDefault(); // 阻止系统默认的右键菜单
            setPosition(event, contextMenu); // 计算并设置菜单的位置
            contextMenu.style.visibility = 'visible'; // 显示菜单
            contextMenu.style.opacity = '1';
        });

        // 如果点击的地方不在菜单内,隐藏菜单
        document.addEventListener('click', function (event) {
            console.log(event.target);
            console.log(contextMenu);
            if (contextMenu !== event.target) {
                contextMenu.style.visibility = 'hidden';
                contextMenu.style.opacity = '0';
            }
        });


        const menuItems = document.querySelectorAll('.menu-item');
        // 为每个菜单项添加事件监听 不优化
        // for (let i = 0; i < menuItems.length; i++) {
        //     menuItems[i].addEventListener('click', function (event) {
        //         console.log(`您点击了菜单项${i + 1}`);
        //                     contextMenu.style.visibility = 'visible';

        //     });
        //     menuItems[i].addEventListener('mousedown', function (event) {
        //         event.stopPropagation();
        //     });
        // }

        // 使用事件委托 优化
        contextMenu.addEventListener('click', function (event) {
            const target = event.target;
            if (target.classList.contains('menu-item')) {
                // indexOf() 返回指定元素在目标队列中首次出现的索引，找不到指定元素，则会返回 -1。
                // call 第一个参数是指定该方法执行时的上下文环境（写谁指向谁），第二个参数，它表示要传递给被调用的方法的参数。
                const index = Array.prototype.indexOf.call(menuItems, target);
                console.log(`您点击了菜单项${index + 1}`);
            }
        });
    </script>

</body>

</html>